package com.yanyilu.qiubite.service;


import com.alibaba.fastjson.JSONObject;
import com.yanyilu.qiubite.entity.*;
import com.yanyilu.qiubite.jpa.*;
import com.yanyilu.qiubite.util.R;
import com.yanyilu.qiubite.util.ResultCode;
import com.yanyilu.qiubite.util.SignUtil;
import com.yanyilu.qiubite.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Service
public class UserService {
    @Autowired
    UserJpa userJpa;
    @Autowired
    CodeJpa codeJpa;

    @Autowired
    JsapiTicketJpa jsapiTicketJpa;

    @Autowired
    SpotJpa spotJpa;

    @Autowired
    GiftJpa giftJpa;

    @Autowired
    StoryIndexJpa storyIndexJpa;


    public void save(User user){
        userJpa.save(user);
    }

    @Transactional
    public R saveUserAndGift(User user){

        Optional<Gift> optional = giftJpa.findById(user.getGiftId());
        if(optional.isPresent()){
            Gift gift = optional.get();
            if(gift.getGiftCount() > 0){
                gift.setGiftCount(gift.getGiftCount()-1);
                userJpa.save(user);
                return R.ok();
            }else {
                return R.error("该奖品已无库存");
            }
        }else {
            return R.error("没有此奖品");
        }
    }

    @Transactional
    public R userDelete(Integer userId){
        userJpa.deleteById(userId);
        storyIndexJpa.deleteByUserId(userId);
        return R.ok();
    }

    public User findById(Integer userId){
        return userJpa.findById(userId).get();
    }

    //管理端用户列表
    public Page<User> spotUserList(Example<User> example, Pageable pagesable){
        return userJpa.findAll(example,pagesable);
    }

    //兑奖码查询用户信息
    public User prizeCodeByUser(String prizeCode){
        return userJpa.prizeCodeByUser(prizeCode);
    }

    public User saveUser(User user) {
        Integer time = (int)(System.currentTimeMillis()/1000);
        Code code = codeJpa.findByPhoneNumberAndCode(user.getPhoneNumber(),user.getCode(),time);
        synchronized (userJpa) {
            if(null != code){
                user.setState(1);
                user.setTaskCount(0);
                User user1 = userJpa.findByPhoneAndSpotId(user.getSpotId(), user.getPhoneNumber());
                if(null == user1){
                    userJpa.save(user);
                }else{
                    user = user1;
                }
            }
        }
        return user;
    }

    //获取配置
    public R getConfig(Integer userid,String requestURI) {
        String appId = userJpa.findAppId(userid);
        if(null == appId){
            return R.error(ResultCode.USER_NOT_EXIST);
        }
        JsapiTicket jsapiTicket = jsapiTicketJpa.findJsapiTicket((int)(System.currentTimeMillis()/1000),appId);
        String jsapi_ticket = "";
        if(null != jsapiTicket){
            jsapi_ticket = jsapiTicket.getJsapiTicket();
        }else{
            jsapi_ticket = getJsapiTicket(appId);
        }
        Map<String, String> sign = SignUtil.sign(jsapi_ticket, requestURI);
        Wconfig wconfig = new Wconfig();
        wconfig.setAppId(appId);
        wconfig.setNonceStr(sign.get("nonceStr"));
        wconfig.setTimestamp(sign.get("timestamp"));
        wconfig.setSignature(sign.get("signature"));
        return R.ok().put("config", wconfig);

    }


    //获取ticket
    public String getJsapiTicket(String appId){
        Spot spot = spotJpa.findByAppId(appId);
        String ticket = "";
        //修改appID，secret
        String tokenUrl="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
                "&appid=" +appId+
                "&secret="+spot.getAppSecret();
        BufferedReader in = null;
        String result = "";
        URL urlGet = null;
        try {
            urlGet = new URL(tokenUrl);
            //启动链接
            HttpURLConnection http = (HttpURLConnection)urlGet.openConnection();
            //设置链接参数与要求
            http.setRequestMethod("GET"); // 必须是get方式请求
            // 建立实际的连接
            http.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = http.getHeaderFields();
            // 遍历所有的响应头字段
/*            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }*/
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(http.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
            //转为json对象
            JSONObject jsonObject = JSONObject.parseObject(result);
            String access_token = "";
            if(jsonObject.containsKey("access_token")){
                access_token = jsonObject.getString("access_token");
            }

            String ticketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket"
            +"?access_token="+access_token+"&type=jsapi";

            urlGet = new URL(ticketUrl);
            //启动链接
            HttpURLConnection http1 = (HttpURLConnection)urlGet.openConnection();
            //设置链接参数与要求
            http1.setRequestMethod("GET"); // 必须是get方式请求
            // 建立实际的连接
            http1.connect();
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(http1.getInputStream()));
            result = "";
            while ((line = in.readLine()) != null) {
                result += line;
            }
            //转为json对象
            JSONObject jsonObject1 = JSONObject.parseObject(result);
            if(jsonObject1.containsKey("ticket")){
                ticket = jsonObject1.getString("ticket");
            }
            String expires_in = jsonObject1.getString("expires_in");
            JsapiTicket jsapiTicket = jsapiTicketJpa.findByAppId(appId);
            if(null == jsapiTicket){
                jsapiTicket = new JsapiTicket();
            }
            jsapiTicket.setAppId(appId);
            jsapiTicket.setEndTime((int)(System.currentTimeMillis()/1000)+Integer.valueOf(expires_in));
            jsapiTicket.setJsapiTicket(ticket);
            jsapiTicketJpa.save(jsapiTicket);

        } catch (MalformedURLException e) {
            e.printStackTrace();
            return null;
        } catch (ProtocolException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return ticket;
    }

    /**
     * 生成兑换码
     * @param userId
     * @return
     */
    public R createPrizeCode(Integer userId) {
        Optional<User> optional = userJpa.findById(userId);
        if(optional.isPresent()){
            User user = optional.get();
            //获取景区id
            Integer spotId = user.getSpotId();
            Integer taskCount = user.getTaskCount();
            Gift gift = giftJpa.findBySpotIdAndTaskCount(spotId,taskCount);
            if(null == gift){
                return R.ok("您未获得任何奖品");
            }else{
                if(null == user.getPrizeCode()){
                    user.setGiftId(gift.getGiftId());
                    user.setGiftName(gift.getGiftName());
                    //生成兑换码
                    user.setPrizeCode(createCode());
                    user.setPrizeState(0);
                    user.setState(0);
                    userJpa.save(user);
                }
            }
            return R.ok().put("user",user);
        }else{
            return R.error(ResultCode.DATA_IS_WRONG);
        }

    }

    //生成兑换码
    public String createCode(){
        String randomStringByLength = StringUtil.getRandomStringByLength(10);
        if(null != userJpa.prizeCodeByUser(randomStringByLength)){
            return createCode();
        }
        return randomStringByLength;
    }
}
